package com.atguigu.gulimall.order.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.exception.NoStockException;
import com.atguigu.common.to.OrderTo;
import com.atguigu.common.to.SkusHasStockVo;
import com.atguigu.common.to.mq.SeckillOrderTo;
import com.atguigu.common.utils.R;
import com.atguigu.common.vo.FareVo;
import com.atguigu.common.vo.MemberResVo;
import com.atguigu.common.vo.OrderVo;
import com.atguigu.gulimall.order.entity.PaymentInfoEntity;
import com.atguigu.gulimall.order.service.PaymentInfoService;
import com.atguigu.gulimall.order.to.OrderCreateTo;
import com.atguigu.gulimall.order.constant.OrderConstant;
import com.atguigu.gulimall.order.entity.OrderItemEntity;
import com.atguigu.gulimall.order.enume.OrderStatusEnum;
import com.atguigu.gulimall.order.frgin.CartFeginService;
import com.atguigu.gulimall.order.frgin.MemberFeginService;
import com.atguigu.gulimall.order.frgin.ProductFeignService;
import com.atguigu.gulimall.order.frgin.WarsFeginService;
import com.atguigu.gulimall.order.interceptor.LoginUserInterceptor;
import com.atguigu.gulimall.order.service.OrderItemService;
import com.atguigu.gulimall.order.vo.*;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.order.dao.OrderDao;
import com.atguigu.gulimall.order.entity.OrderEntity;
import com.atguigu.gulimall.order.service.OrderService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {

//    本地线程共享
    private ThreadLocal<OrderSubmitVo> confirmVoThreadLocal = new ThreadLocal<>();
    @Autowired
    private MemberFeginService memberFeginService;
    @Autowired
    private CartFeginService cartFeginService;
    @Autowired
    private ThreadPoolExecutor executor;
    @Autowired
    private WarsFeginService warsFeginService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private ProductFeignService productFeignService;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private PaymentInfoService paymentInfoService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                new QueryWrapper<OrderEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public OrderConfirmVo confirmOrder() {
        OrderConfirmVo orderConfirmVo = new OrderConfirmVo();
//        获取登录的id
        MemberResVo memberResVo = LoginUserInterceptor.loginUser.get();
//        在异步任务执行之前，让它放一下数据，先从主线程拿到原来的数据
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

//        1、远程调用收货地址--->使用线程池异步调用服务（节省时间）
        CompletableFuture<Void> getAddressFuture = CompletableFuture.runAsync(() -> {
            /**
             * 从主线程拿到原来的数据，在父线程里面都共享出来RequestContextHoldereption: Loa
             * 只有共享出来，拦截器里面才会有数据，也即是获取之前的请求，每一个线程都来共享之前的请求数据
             */
            RequestContextHolder.setRequestAttributes(requestAttributes);
            List<MemberAddressVo> address = memberFeginService.getAddress(memberResVo.getId());
            orderConfirmVo.setMemberAddress(address); // 收货地址
        }, executor);

//        2、远程调用购物车的购物项（由于必须登录才能获取到购物车的数据，fegin远程调用会丢失请求头数据，所以需要拦截器更换新请求头）
        CompletableFuture<Void> cartFuture = CompletableFuture.runAsync(() -> {
//            每一个线程进来之前都共享之前的请求数据
            RequestContextHolder.setRequestAttributes(requestAttributes);
            List<OrderItemVo> currentUserCartItems = cartFeginService.getCurrentUserCartItems();
            orderConfirmVo.setOrderItemVos(currentUserCartItems);
//            查询到购物车商品之后，再查询这些商品的所有库存信息
        }, executor).thenRunAsync(()->{
            List<OrderItemVo> orderItemVos = orderConfirmVo.getOrderItemVos();
//            批量查询每一个商品的库存信息
            List<Long> collect = orderItemVos.stream().map(item -> item.getSkuId()).collect(Collectors.toList());
//            远程查询库存系统来查相应的库存信息
            R hasStock = warsFeginService.getSkusHasStock(collect);
//            得到每一个商品的库存状态信息
            List<SkusHasStockVo> data = hasStock.getData(new TypeReference<List<SkusHasStockVo>>() {
            });
            if (data != null){
                Map<Long, Boolean> map = data.stream().collect(Collectors.toMap(SkusHasStockVo::getSkuId, SkusHasStockVo::getHasStock));
                orderConfirmVo.setStocks(map);
            }
        });

//        3、优惠券信息（会员积分信息）
        Integer integration = memberResVo.getIntegration();
        orderConfirmVo.setIntegration(integration);

//        4、其他数据自动计算

//        5、防重令牌
        /**
         * 在订单确认页来到之前，可以为这个页面生成一个令牌，提交订单的时候顺便带上这个令牌
         * 然后验令牌保证幂等性
         * 这个防重领牌子保存到redis中
         *下一次验证就去redis中拿即可，然后给页面放一个令牌，服务器也放一个
         */
        String token = UUID.randomUUID().toString().replace("-", "");
//        参数：用户id，令牌，30分钟过期时间
        redisTemplate.opsForValue().set(OrderConstant.USER_ORDER_TOKEN_PREFIX+memberResVo.getId(),token,30, TimeUnit.MINUTES);
//        给页面，服务器各一个防重令牌
        orderConfirmVo.setOrderToken(token);
        try {
//         等待上面所有线程都执行完
            CompletableFuture.allOf(getAddressFuture,cartFuture).get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return orderConfirmVo;
    }

    /**
     * 下单请求服务
     *
     * @param vo
     * @return
     */
    @Transactional
    @Override
    public SubmitOrderResponseVo submitOrder(OrderSubmitVo vo) {
//        创建订单方法之前，将页面传来的数据都可以放到ThreadLocal本地线程变量里面
        confirmVoThreadLocal.set(vo);
        SubmitOrderResponseVo response = new SubmitOrderResponseVo();
//        得到登录后的用户
        MemberResVo memberResVo = LoginUserInterceptor.loginUser.get();
//        响应状态（0为成功）
        response.setCode(0);
        /**
         * 1、验证防重令牌，令牌是否合法，浏览器传过来的令牌跟redis中的令牌比较【并且令牌对比和删除必须是原子性的】
         *  脚本的意思：如果redis调用get方法来获取一个key的值等于传过来的值，就会返回令牌删除，否则返回0
         *  最终脚本：返回的是0或1，如果获取指定的值，这个值如果不存在就删不了就返回0，如果存在就会删除，删除成功了返回1，否则返回0
         *  0：令牌验证失败
         *  1：删除成功，也即令牌对比成功了才能删除成功
         */
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
//        如果使用token机制，就应该使用脚本的方式对比和删除令牌
        String orderToken = vo.getOrderToken();// 得到页面传过来的token
        /**
         * 原子验证防重令牌和删锁令牌操作的脚本（把前端页面的token与服务器的token对比，成功就删除。整个过程原子性）
         * 第一个参数：脚本信息和返回的脚本类型
         * 第二个参数：验证的key
         * 第三个参数：对比的值
         */
        Long result = redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class),
                Arrays.asList(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResVo.getId()), orderToken);

        if (result == 0L){
            // 防重令牌验证失败
            response.setCode(1); // 失败就返回给前端为1
            return response;
        }else{
            // 防重令牌验证成功，说明删除令牌成功
            // 令牌验证通过就进行创建下单操作：去服务器验证令牌，创建订单，验价格，锁库存等操作...
            // 1、创建订单
            OrderCreateTo order = createOrder();
            // 2、验价
            BigDecimal payAmount = order.getOrder().getPayAmount();
            BigDecimal payPrice = vo.getPayPrice();
            if (Math.abs(payAmount.subtract(payPrice).doubleValue())< 0.01){
                // 金额对比
                // 3、保存订单数据
                saveOrder(order);
                // 4、库存锁定，只要有异常，就回滚订单数据
                // 订单号：给哪个订单锁的库存。
                // 所有订单项（商品的skuid，锁了几件商品，商品名字）
                WareSkuLockVo lockVo = new WareSkuLockVo();
                lockVo.setOrderSn(order.getOrder().getOrderSn());//为这个订单号锁定库存
                List<OrderItemVo> locks = order.getOrderItems().stream().map(item -> {
                    OrderItemVo itemVo = new OrderItemVo();
                    itemVo.setSkuId(item.getSkuId());
                    itemVo.setCount(item.getSkuQuantity());//订单项的数量
                    itemVo.setTitle(item.getSkuName());
                    return itemVo;
                }).collect(Collectors.toList());
                lockVo.setLocks(locks);
                // TODO 只要订单保存成功就远程调用库存服务，然后锁库存，防止订单支付成功以后还没有库存
                R r = warsFeginService.orderLockStock(lockVo);
                if (r.getCode() == 0){
//                    库存锁定成功
                    response.setOrder(order.getOrder());
                    // TODO 订单创建成功就发送消息给MQ
                    rabbitTemplate.convertAndSend("order-event-exchange","order.create.order",order.getOrder());
                    return response;
                }else{
//                    库存锁定失败了，抛异常回滚事物
                    String msg = (String) r.get("msg");
                    throw new NoStockException(msg);
                }
            }else{
//                金额对比失败
                response.setCode(2);
                return response;
            }
        }
    }

    @Override
    public OrderEntity getOrderByOrderSn(String orderSn) {
        OrderEntity orderEntity = this.getOne(new QueryWrapper<OrderEntity>().eq("order_sn", orderSn));
        return orderEntity;
    }

    /**
     * 自动关单
     *  想要关单，其实就是把订单表里面的状态0修改为4即可
     *  但是改之前要查询一下，万一已经支付成功了，来到消息队列里面的这个消息是每一个订单都过来的，但是有些订单已经成功了
     *  那么成功的就要在关单之前一定要查询这个订单当前状态是什么
     * @param entity
     */
    @Override
    public void cloneOrder(OrderEntity entity) {
        // 关闭订单之前，先来查询这个订单的最新状态
        // 因为之前订单创建成功，直接发的是数据库保存的这个对象，所以数据库保存的这个对象是直接有自鞥id的，所以拿到这个订单的id
        OrderEntity orderEntity = this.getById(entity.getId());
        // 判断当前的状态，什么情况下需要关单？----只有付款当中才能关单
        if (orderEntity.getStatus() == OrderStatusEnum.CREATE_NEW.getCode()){
            // 就进行关单（改一个状态）
            OrderEntity update = new OrderEntity();
            update.setId(entity.getId());
            update.setStatus(OrderStatusEnum.CANCLED.getCode());
            this.updateById(update);
            OrderTo orderTo = new OrderTo();
            BeanUtils.copyProperties(orderEntity,orderTo);
            orderTo.setStatus(OrderStatusEnum.CANCLED.getCode());
            // 因为远程调用的问题，需要在这里进行关库存的订单
            warsFeginService.updateOrder(orderTo);

            // 只要订单释放了，再给订单服务的交换机发一个消息，然后让订单服务的这个交换机与库存绑定的库存释放的队列进行发送消息，告诉订单释放成功
            try {
                rabbitTemplate.convertAndSend("order-event-exchange","order.release.other",orderTo);
            }catch (Exception e){
                // TODO 将没有发送成功的消息进行重新发送
            }
        }
    }

    @Override
    public PayVo getOrderPay(String orderSn) {
        PayVo payVo = new PayVo();
        // 查询订单数据
        OrderEntity orderEntity = this.getOrderByOrderSn(orderSn);
        BigDecimal decimal = orderEntity.getPayAmount().setScale(2, BigDecimal.ROUND_UP);
        payVo.setOut_trade_no(orderEntity.getOrderSn());
        payVo.setTotal_amount(decimal.toString());
        List<OrderItemEntity> order_sn = orderItemService.list(new QueryWrapper<OrderItemEntity>().eq("order_sn", orderSn));
        // 拿到商品的第一个名字
        OrderItemEntity entity = order_sn.get(0);
        if (entity != null){
            payVo.setBody(entity.getSkuAttrsVals());
            payVo.setSubject(entity.getSkuName());
        }
        return payVo;
    }

    /**
     * 分页查询当前登录后的用户的所有订单列表页的详情数据
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPageWithItem(Map<String, Object> params) {
        // 获取当前用户
        MemberResVo memberResVo = LoginUserInterceptor.loginUser.get();
        IPage<OrderEntity> page = this.page(new Query<OrderEntity>().getPage(params),
                new QueryWrapper<OrderEntity>().eq("member_id", memberResVo.getId()).orderByDesc("id"));
        // 把每一个订单拿来在查询一下订单的dingdanxiang
        List<OrderEntity> order_sn = page.getRecords().stream().map(order -> {
            // 按照订单号来查询订单项的详情信息
            List<OrderItemEntity> itemEntities = orderItemService.list(new QueryWrapper<OrderItemEntity>().eq("order_sn", order.getOrderSn()));
            order.setItemEntities(itemEntities);
            return order;
        }).collect(Collectors.toList());
        page.setRecords(order_sn);
        return new PageUtils(page);
    }

    /**
     * 处理支付宝的支付结果
     * @param vo
     * @return
     */
    @Override
    public String handlePayResult(PayAsyncVo vo) {
        // 保存支付流水信息
        PaymentInfoEntity infoEntity = new PaymentInfoEntity();
        infoEntity.setAlipayTradeNo(vo.getTrade_no());
        infoEntity.setOrderSn(vo.getOut_trade_no());
        infoEntity.setPaymentStatus(vo.getTrade_status());
        infoEntity.setCallbackTime(vo.getNotify_time());
        paymentInfoService.save(infoEntity);
        // 修改订单状态信息
        if (vo.getTrade_status().equals("TRADE_SUCCESS") ||  vo.getTrade_status().equals("TRADE_FINISHED")) {
            // 支付成功状态
            String outTradeNo = vo.getOut_trade_no();
            this.baseMapper.updateOrderStatus(outTradeNo,OrderStatusEnum.PAYED.getCode());
        }
        // 固定写法。必须写success，否则支付宝不识别成功
        return "success";
    }

    /**
     * 订单处理MQ的秒杀信息
     * 只要一秒杀成功，队列里面已收到消息，订单服务就会为我们创建一个订单
     * @param seckillOrder
     */
    @Override
    public void createSeckillOrder(SeckillOrderTo seckillOrder) {
        //TODO 保存订单的信息(还有其他细节)
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderSn(seckillOrder.getOrderSn());
        orderEntity.setMemberId(seckillOrder.getMemberId());
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode()); //待付款
        BigDecimal multiply = seckillOrder.getSeckillPrice().multiply(new BigDecimal("" + seckillOrder.getNum()));
        orderEntity.setPayAmount(multiply); //支付的所有信息，要付多少钱
        this.save(orderEntity);
        //保存订单项的信息
        OrderItemEntity orderItemEntity = new OrderItemEntity();
        orderItemEntity.setOrderSn(seckillOrder.getOrderSn());
        orderItemEntity.setRealAmount(multiply); //真实要付的价格
        orderItemEntity.setSkuQuantity(seckillOrder.getNum());//买了多少件
        orderItemService.save(orderItemEntity);
    }

    /**
     * 保存订单
     * @param order
     */
    private void saveOrder(OrderCreateTo order) {
        OrderEntity orderEntity = order.getOrder();
        orderEntity.setModifyTime(new Date());
        this.save(orderEntity);
        OrderTo orderTo = new OrderTo();
        BeanUtils.copyProperties(orderEntity,orderTo);
        warsFeginService.createOrder(orderTo);
//        保存所有订单项
        List<OrderItemEntity> orderItems = order.getOrderItems();
        orderItemService.saveBatch(orderItems);
    }

    /**
     * 1、创建订单--验证令牌成功后的第一步
     * 下订单流程
      * @return
     */
    private OrderCreateTo createOrder() {
        OrderCreateTo createTo = new OrderCreateTo();
//        1、生成订单号(使用mybatisplus提供的订单id不重复，当做订单号)
        String orderSn = IdWorker.getTimeId();
//        按照指定的订单号构建一个订单
        OrderEntity orderEntity = buildOrder(orderSn);
//        2、获取到所有的订单项
        List<OrderItemEntity> itemEntities = buildOrderItems(orderSn);
//        3、验价格 计算出订单里面的信息，最终价格
//        参数一：哪个订单，参数二：订单项数据，最终计算来的价格会放在订单的实体对象里面
//        TODO 需要断点调试orderEntity,itemEntities的属性值是否改变
        computePrice(orderEntity,itemEntities);
        createTo.setOrder(orderEntity);
        createTo.setOrderItems(itemEntities);
        return createTo;
    }

    /**
     * 根据订单号构建一个订单
     * @param orderSn
     * @return
     */
    private OrderEntity buildOrder(String orderSn) {
        MemberResVo respVo = LoginUserInterceptor.loginUser.get();//获取登录后的用户
//        1、整个订单的生成就应该是这个OrderEntity实体类的信息，这个实体类信息里面保存好订单号
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderSn(orderSn);//保存订单号
        orderEntity.setMemberId(respVo.getId());//会员id
        // 获取到页面传递来的数据
        OrderSubmitVo orderSubmitVo = confirmVoThreadLocal.get();
        // 2、远程查询收货人的地址信息和计算运费信息
        R fare = warsFeginService.getFare(orderSubmitVo.getAddrId());
        // 解析运费信息
        FareVo fareResp = fare.getData(new TypeReference<FareVo>() {
        });
//        给订单里面填充运费信息
        orderEntity.setFreightAmount(fareResp.getFare());
//        给订单里面填充收货人信息
        orderEntity.setReceiverCity(fareResp.getAddressVo().getCity());
        orderEntity.setReceiverDetailAddress(fareResp.getAddressVo().getDetailAddress());
        orderEntity.setReceiverName(fareResp.getAddressVo().getName());
        orderEntity.setReceiverPhone(fareResp.getAddressVo().getPhone());
        orderEntity.setReceiverPostCode(fareResp.getAddressVo().getPostCode());
        orderEntity.setReceiverProvince(fareResp.getAddressVo().getProvince());
        orderEntity.setReceiverRegion(fareResp.getAddressVo().getRegion());

//        设置订单的相关状态信息
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());
        orderEntity.setAutoConfirmDay(7);//自动确认时间7天
        return orderEntity;
    }

    /**
     * 根据订单号创建每一个订单项
     * @param orderSn
     * @return
     */
    private List<OrderItemEntity> buildOrderItems(String orderSn) {
//        3、填充订单里面的订单项信息
//        最后确认每个购物项的价格，即使后台调价，最终还是会根据现在确认的价格来进行购买商品
//        远程获取当前用户购物车的购物项
        List<OrderItemVo> currentUserCartItems = cartFeginService.getCurrentUserCartItems();
        if (currentUserCartItems != null && currentUserCartItems.size() > 0){
//            每一个购物车里面的购物项数据都有映射成最终的订单信息
            List<OrderItemEntity> itemEntities = currentUserCartItems.stream().map(cartItem -> {
//                构建出每个订单项，也就是说每一个订单信息，都要构建成一个订单项，最终返回订单项信息
                OrderItemEntity itemEntity = buildOrderItem(cartItem);
                itemEntity.setOrderSn(orderSn);
                return itemEntity;
            }).collect(Collectors.toList());
            return itemEntities;
        }
        return null;
    }

    /**
     * 根据购物车的购物项生成某一个订单项
     * @param cartItem
     * @return
     */
    private OrderItemEntity buildOrderItem(OrderItemVo cartItem) {
        OrderItemEntity itemEntity = new OrderItemEntity();
//        1、订单信息：订单号

//        2、商品spu信息
        Long skuId = cartItem.getSkuId();
        R r = productFeignService.getSpuInfoBySkuId(skuId);
        SpuInfoVo data = r.getData(new TypeReference<SpuInfoVo>() {
        });
        itemEntity.setSpuId(data.getId());
        itemEntity.setSpuName(data.getSpuName());
        itemEntity.setSpuBrand(data.getBrandId().toString());
        itemEntity.setCategoryId(data.getCatalogId());

//        3、商品sku信息
        itemEntity.setSkuId(cartItem.getSkuId());
        itemEntity.setSkuName(cartItem.getTitle());
        itemEntity.setSkuPic(cartItem.getImage());
        itemEntity.setSkuPrice(cartItem.getPrice());
        String skuAttr = StringUtils.collectionToDelimitedString(cartItem.getSkuAttr(),";");
        itemEntity.setSkuAttrsVals(skuAttr);
        itemEntity.setSkuQuantity(cartItem.getCount());

//        4、优惠券信息【忽略不做】

//        5、积分信息
        itemEntity.setGiftGrowth(cartItem.getPrice().multiply(new BigDecimal(cartItem.getCount().toString())).intValue());
        itemEntity.setGiftIntegration(cartItem.getPrice().multiply(new BigDecimal(cartItem.getCount().toString())).intValue());

//        6、订单项的价格相关信息
        itemEntity.setPromotionAmount(new BigDecimal("0"));
        itemEntity.setCouponAmount(new BigDecimal("0"));
        itemEntity.setIntegrationAmount(new BigDecimal("0"));
//        当前订单项的实际金额计算，总价乘以数量
        BigDecimal orign = itemEntity.getSkuPrice().multiply(new BigDecimal(itemEntity.getSkuQuantity().toString()));
//        总额减去各种优惠
        BigDecimal subtract = orign.subtract(itemEntity.getCouponAmount()).subtract(itemEntity.getPromotionAmount()).subtract(itemEntity.getIntegrationAmount());
        itemEntity.setRealAmount(subtract);
        return itemEntity;
    }

    /**
     * 计算价格，最终的验价
     * @param orderEntity 订单实体
     * @param itemEntities 全部订单项
     */
    private void computePrice(OrderEntity orderEntity, List<OrderItemEntity> itemEntities) {
        BigDecimal total = new BigDecimal("0.0");// 默认总价格
        BigDecimal coupon = new BigDecimal("0.0");
        BigDecimal integration = new BigDecimal("0.0");
        BigDecimal promotion = new BigDecimal("0.0");
        BigDecimal gift = new BigDecimal("0.0");
        BigDecimal growth = new BigDecimal("0.0");

//        订单总价，叠加每一个订单项的总额信息，也即所有购物项相加的总额
        for (OrderItemEntity entity : itemEntities) {
            coupon = coupon.add(entity.getCouponAmount());
            integration = integration.add(entity.getIntegrationAmount());
            promotion = promotion.add(entity.getPromotionAmount());
            total = total.add(entity.getRealAmount());
//            当前订单能获得的积分信息
            gift = gift.add(new BigDecimal(entity.getGiftIntegration().toString()));
            growth = growth.add(new BigDecimal(entity.getGiftIntegration().toString()));
//            计算每一项的价格：单价乘以数量
            // BigDecimal decimal = entity.getSkuPrice().multiply(new BigDecimal(entity.getSkuQuantity().toString()));
        }
//        1、订单价格相关
        orderEntity.setTotalAmount(total);
//        设置应付总额
        orderEntity.setPayAmount(total.add(orderEntity.getFreightAmount()));
        orderEntity.setPromotionAmount(promotion);
        orderEntity.setIntegrationAmount(integration);
        orderEntity.setCouponAmount(coupon);
//        设置积分信息
        orderEntity.setIntegration(gift.intValue());
        orderEntity.setGrowth(growth.intValue());

        orderEntity.setDeleteStatus(0);//0代表未删除状态
    }
}
